iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 1
0
自我挑戰組

三十天說寫就寫的Coding文章系列 第 1

Day1 - 來寫Javascript吧!

  • 分享至 

  • xImage
  •  

哈囉,大家好!

歡迎來到三十天說寫就寫的Coding文章。

有人說「 每個人的一生中至少要有兩次衝動,一次為奮不顧身的愛情,一次為說走就走的旅行。 」

套在Coding的人上,也就是要有幾篇說寫就寫的文章吧!


今天來寫一下Javascript,並使用Javascript來實作一個Stack物件。

首先,我們要先複習一下Javascript的apply跟call方法,因為我們等一下會用到。

在javascript裡,每個function都擁有apply跟call方法,可以用來讓函數方法執行時的this綁定為要使用該方法的物件上,這裡我主要介紹apply。

fun.apply(thisArg, [argsArray])

第一個參數是要使用該function方法(簡稱func)的物件,當第一個參數的值是null或undefined時,非嚴格模式下,func套用的this會是全域物件,否則為null跟undefined。

第二個參數則是將引數們包在一個Array傳給讓function方法使用的參數們。

call方法和apply大同小異,差別只在參數要一個一個輸入。

  • Call的語法如下(參考MDN)
fun.call(thisArg, arg1, arg2, ...)

使用範例:

在JS裡我們要比較各個數值中的最大值,可以使用Math.max()方法

舉例: Math.max(1, 2, 3, 4) // 該方法返回最大值4

使用Math.max方法要將要比較的數值一個一個輸入進去,如果現在我們要找出一個Array內各個數值的最大值,
這時候沒有apply或call方法,要對Array做很多處理才能算出數值,多不方便啊。

是時候輪到apply方法出場了。

   const max = (...args) => Math.max.apply(null, args); 
   const arr = [1,2,3,4,5];
   max(...arr); // 該方法返回最大值5

從上面的範例可以看到,使用apply方法,一行就可以將我們要使用的max方法使用apply成一個適合array使用的function,多麼簡單就完成了這個需求阿!


現在我們會使用apply方法了,該進到我們今天的主題: 實作一個Stack。

Stack(堆疊)是一個依照後進先出(LIFO)原則設計的有序集合。

我們可以想像我們在一個塞好幾個羽球的長筒,最先放進去的一定是最後拿出來,最後放進去的反而可以先拿出來。

這個比喻完全適用在Stack的行為上。

好,現在我們要來設計一個Stack的類別。

Stack類別下面要擁有如下方法:

  • add(elements): 加入一個(或多個)元素到堆疊頂部。
  • pop(): 移除堆疊的最上層元素,同時返回被移除的元素。
  • last(): 取得堆疊的最上層元素,但並不移除堆疊元素。
  • size(): 取得堆疊元素總數。
  • clear(): 清空所有堆疊。
  • isEmpty(): 確認堆疊內有無元素,有則返回false,沒有則返回true。

讓我們開始寫一個Stack的基本骨架

class Stack {
    length = 0;
    constructor() {}
    add() {}
    pop() {}
    last() {}
    size() {}
    clear() {}
    isEmpty() {}
}

Ok,現在我們的class大致有了個樣子,接下來,我們要實作add方法!

add(...elems) {
    Array.prototype.push.apply(this, elems);
}

加入了Add方法後,我們來建立這個Stack物件,並且測試一下。

const stack = new Stack();
console.log('Stack Length:', stack.length);
stack.add('el1', 'el2');
console.log('Stack Length:', stack.length);

神奇的地方來囉!

// 輸出結果:
// Stack Length: 0
// Stack Length: 2

明明是使用Array的方法,但是Stack類別的length屬性居然也跟著改變了!

原來,Array方法本身會增加Array物件屬性的長度(length),現在我們用apply將Array套用在Stack的this上,因為this指向改變,所以push改為影響到Stack的length屬性。

只要好好把握這個原理,用Array內建的方法就可以完成許多建構Stack方法要處理的事情囉!


Ok,最後最後,我們舉一反三,完成一個簡潔的Stack,並且進行簡單的測試。

精髓盡在程式碼中,仔細感受一下吧!

如果有地方看不明白或不了解,建議多趁這個機會查詢,並進一步了解JS的語法跟Array的方法。

class Stack {
    length = 0;
    constructor() {}
    add(...elems) {
        Array.prototype.push.apply(this, elems);
    }
    pop() {
        return Array.prototype.pop.apply(this);
    }
    last() {
        return this[this.length-1];
    }
    size() {
        return this.length;
    }
    clear() {
        Array.prototype.splice.apply(this, [0, this.length]);
    }
    isEmpty() {
        return this.length === 0;
    }
}

最後這是測試用代碼,建議讀者親自操作,透過主控台檢視下Stack物件的狀態,才會有新的體會!

    console.log('Stack', stack);
    console.log('Stack Length:', stack.length);
    stack.add('el1', 'el2');
    console.log('Stack Length:', stack.length);
    const popElem = stack.pop();
    console.log('Stack Length:', stack.length);
    console.log('PopElem:', popElem);
    console.log('last: ', stack.last());
    stack.add('el3','el4', 'el5');
    console.log('stack: ', stack);
    stack.clear();
    console.log('stack: ', stack);
    console.log('IsEmpty: ', stack.isEmpty());

好的,以上這就是今天的全部內容囉,希望各位能夠照著操作,並且有滿滿的收穫。

我們明天見,掰掰!


下一篇
Day2 - 學習主從模式
系列文
三十天說寫就寫的Coding文章2
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言